package com.yxt.user.service.impl;

import com.yxt.common.utils.JwtUtil;
import com.yxt.user.config.ResourceServerConfig;
import com.yxt.user.entity.MenuEntity;
import com.yxt.user.mapper.MenuMapper;
import com.yxt.user.mapper.RoleMapper;
import com.yxt.user.mapper.RoleMenuMapper;
import com.yxt.user.mapper.UserRoleMapper;
import com.yxt.user.service.MenuService;
import com.yxt.user.vo.MenuVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxt.common.utils.PageUtils;
import com.yxt.common.utils.Query;



@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, MenuEntity> implements MenuService {

    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MenuEntity> page = this.page(
                new Query<MenuEntity>().getPage(params),
                new QueryWrapper<MenuEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<MenuVO> listWithTree() {

        OAuth2AuthenticationDetails authentication = (OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
        Map<String, String> stringStringMap = JwtUtil.decodeToken(authentication.getTokenValue(), ResourceServerConfig.PUBLIC_KEY);

        String userName = stringStringMap.get("user_name");

        List<MenuEntity> entities = menuMapper.getTreeWithUserName(userName);
        //1、查出所有分类
       // List<MenuEntity> entities = baseMapper.selectList(null);

        //2、组装成父子的树形结构
        //2.1）、找到所有的一级分类
        List<MenuVO> level1Menus = entities.stream().filter(menuEntity ->
                menuEntity.getParentid() == 0
        ).map((menu)->{
            MenuVO menuVO = new MenuVO();
            menuVO.setName(menu.getName());
            menuVO.setPath(menu.getPath());
            menuVO.setRedirect(menu.getRedirect());
            menuVO.setUrl(menu.getUrl());
            menuVO.setMenuId(menu.getMenuId());

            if( !StringUtils.isEmpty(menu.getTitle()) || !StringUtils.isEmpty(menu.getIcon())){
                MenuVO.Meta meta = new MenuVO.Meta();
                meta.setIcon(menu.getIcon());
                meta.setTitle(menu.getTitle());
                menuVO.setMeta(meta);
            }
            menuVO.setChildren(getChildrens(menuVO,entities));
           // menu.setChildren(getChildrens(menu,entities));
            return menuVO;
        }).collect(Collectors.toList());

        return level1Menus;
    }

    //递归查找所有菜单的子菜单
    private List<MenuVO> getChildrens(MenuVO root,List<MenuEntity> all){

        List<MenuVO> children = all.stream().filter(menuEntity -> {
            return menuEntity.getParentid() == root.getMenuId();
        }).map(menuEntity -> {
            //1、找到子菜单
            MenuVO menuVO = new MenuVO();
            menuVO.setName(menuEntity.getName());
            menuVO.setPath(menuEntity.getPath());
            menuVO.setRedirect(menuEntity.getRedirect());
            menuVO.setUrl(menuEntity.getUrl());
            menuVO.setMenuId(menuEntity.getMenuId());

            MenuVO.Meta meta = new MenuVO.Meta();
            meta.setIcon(menuEntity.getIcon());
            meta.setTitle(menuEntity.getTitle());
            menuVO.setMeta(meta);
            menuVO.setChildren(getChildrens(menuVO,all));
            return menuVO;
        }).collect(Collectors.toList());

        return children;
    }

}